home *** CD-ROM | disk | FTP | other *** search
- Path: keats.ugrad.cs.ubc.ca!not-for-mail
- From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
- Newsgroups: comp.lang.c
- Subject: Re: State machine design
- Date: 25 Mar 1996 08:21:33 -0800
- Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
- Message-ID: <4j6h6dINNd6o@keats.ugrad.cs.ubc.ca>
- References: <4j0ikl$9t5@news.NetVision.net.il>
- NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
-
- In article <4j0ikl$9t5@news.NetVision.net.il>,
- Uri Simchoni <simchoni@netvision.net.il> wrote:
- >Hi,
- >
- >I'm designing what I call a communication server. This a program which
- >receives messages from the network sends these messages to a device over
- >the serial port according to the device's proprietary protocol, and sends
- >the device's reply back over the network.
- >
- >What I have in mind is to split the program into three basic modules. The
- >first one handles the RS232 communications, the second handles the
- >protocol logic and the third handles network traffic. Due to operating
- >system constraints (the OS is DOS and the computer the program runs on
- >should do other things), I can't use a model of "wait for a call from the
- >network, process that call and send your reply". I have to use some kind
-
- So don't use DOS! Duh.
-
- Why bang your head against a wall when you can load up FreeBSD or Linux?
-
- The sort of problem you are talking about has already been solved in these
- systems, or is readily implemented.
-
- Advantages:
-
- the OS already has efficient, interrupt-driven serial drivers. You just
- learn the POSIX.1 tty API and use that.
-
- there is support for multi-port serial cards, so expanding to handling
- modem banks would be quite easy.
-
- there is networking support for a bunch of different protocols, but
- primarily TCP/IP.
-
- there is pre-emptive multi-tasking.
-
- these things are tested by lots of users who _use_ networking and
- serial stuff day in and day out! Writing your own code would be yet
- another from-scratch deal that has to be heavily tested.
-
- these systems are _free_!
-
- What you are demanding could be easily implemented in a fun-filled afternoon
- under a UNIX system.
-
-
- >of a state machine in the protocol logic module. The protocol logic
- >module will have functions that get called by the other modules whenever
- >an event occurs (clock tick, character arriving from the serial port,
- >request from the network, etc.)
-
- In other words, you want to re-invent the wheel. These things are already done
- inside the Linux kernel. Multiplexing between characters arriving from the
- serial port and messages from the network can be done synchronously using the
- select() operating system call, which can simultaneously monitor a number of
- file descriptors for input, output or exception conditions, and tell you which
- ones are ready for action. It can wait forever, or for the specified timeout
- period.
-
- If you insist on using a clock interrupt for something, you set a C signal
- handler, and start a periodic alarm timer.
-
- It's extremely easy once you learn the API. You just open the right files and
- sockets and off you go!
-
- >After this LONG outline of the problem I get to my question. I'm
- >considering several designs for the state machine interface. One is to
- >have a distinct function for each type of event. The function decides
- >what to do according to module's internal data. Another is to have a
- >pointer to the function that handles all events for the current state. If
- >the state should change, the pointer is modified. Another design lays
- >somewhere in between - to have a sparate function for each type of event
- >and each state.
-
- The accepted methodology is to split things into lower-half/upper-half drivers.
- For example, for handling the serial input, you buffer the characters into a
- queue inside an autonomous lower-half interrupt handler. The rest of the
- program makes requests by calling the upper-half code to read the characters
- from the queue. The upper and lower halves communicate using shared data
- structures, usually semaphores and queues, which allow the consumer of data to
- wait when the queue is empty, and the producer to block or do some flow control
- operation when the queue is full.
-
- You can set up some sort of asynchronous high-level notification of the arrival
- of data that roughly corresponds to low-level interrupts, but in a simple
- application like this you might just get away with polling all the various
- queues for input and making a decision about what to do based on what messages
- have arrived over the network or from the serial protocol.
-
- The facilities to do all this are already implemented for you in a decent OS,
- you just write the code to initialize and organize the facilities to do the
- task.
-
- >Since my experience with such program is nearly zero, I cannot tell if
- >one design is preferable over the other (or if there's a better way of
- >doing these things). I'd appreciate anyone's input on the subject. I
- >think the primary issues that should be considered are ease of
- >implementation(handling reentrancy problems, etc), debugging, and
- >readability. Ease of making changes isn't a major issue since the serial
- >protocol is fixed and well established.
-
- You might _learn_ some things by doing all this yourself: but a reading decent
- textbook on OS design might be helpful, followed up by research into
- communication protocols, device drivers and such. But a practical solution
- calls for using software that already has these things.
- --
-
-